package com.hptpd.questionnairesurvey.service.impl;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.hptpd.questionnairesurvey.assets.Constant;
import com.hptpd.questionnairesurvey.component.RedisService;
import com.hptpd.questionnairesurvey.component.Result;
import com.hptpd.questionnairesurvey.domain.Department;
import com.hptpd.questionnairesurvey.domain.User;
import com.hptpd.questionnairesurvey.repository.DepartmentRep;
import com.hptpd.questionnairesurvey.repository.UserRep;
import com.hptpd.questionnairesurvey.service.IUserService;
import com.hptpd.questionnairesurvey.service.base.BaseServiceImpl;
import com.hptpd.questionnairesurvey.utils.AbstractMyBeanUtils;
import com.hptpd.questionnairesurvey.vo.UserTreeVo;
import com.hptpd.questionnairesurvey.vo.UserVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * \* Created with IntelliJ IDEA.
 * \* Date: 2019-07-16 09:15
 * \*
 * \* Description: 积分实体
 * \
 *
 * @author waiterlong
 */
@Service("iUserService")
public class UserServiceImpl extends BaseServiceImpl implements IUserService {
    private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    private static String projTag = "questionnaire_survey_";

    @Value("${alibaba.short-message.accesskeyid}")
    private String shortMessageAccesskeyId;
    @Value("${alibaba.short-message.secret}")
    private String shortMessageSecret;
    @Value("${alibaba.short-message.domain}")
    private String shortMessageDomain;
    @Value("${alibaba.short-message.action}")
    private String shortMessageAction;
    @Value("${alibaba.short-message.signname}")
    private String shortMessageSignName;
    @Value("${alibaba.short-message.temp}")
    private String shortMessageTemp;

    @Resource(name = "userRep")
    private UserRep userRep;
    @Resource(name = "departmentRep")
    private DepartmentRep departmentRep;
    @Resource
    private RedisService redisService;

    @Override
    public Result getUserTree(@NotNull Map<String, Object> paramMap) {
        logger.debug("getUserTree paramMap: {}", paramMap);

        List<Department> rootDepartments = departmentRep.findByParentDepartmentIs(null);
        if (null == rootDepartments || rootDepartments.isEmpty()) {
            return Result.fail();
        }
        List<UserTreeVo> destUserTreeVos = UserTreeVo.convertDepartment(rootDepartments);
        Stack<UserTreeVo> userTreeVoStack = new Stack<>();
        userTreeVoStack.addAll(destUserTreeVos);
        //非递归方式得出前端树组件需要的数据格式
        while (!userTreeVoStack.isEmpty()) {
            UserTreeVo tUserTreeVo = userTreeVoStack.pop();
            Department department = departmentRep.findByIdIs(Integer.parseInt(tUserTreeVo.getId()));
            List<Department> departments = department.getChildDepartments();

            if (null == departments || departments.isEmpty()) {
                List<User> users = department.getUsers();
                tUserTreeVo.setChildren(UserTreeVo.convertUser(users));
            } else {
                List<Department> childDepartments = department.getChildDepartments();
                List<UserTreeVo> userTreeVos = UserTreeVo.convertDepartment(childDepartments);
                userTreeVoStack.addAll(userTreeVos);
                userTreeVos.addAll(UserTreeVo.convertUser(department.getUsers()));
                tUserTreeVo.setChildren(userTreeVos);
            }
        }
        return Result.ok(destUserTreeVos);
    }

    @Override
    public Result wxLogin(@NotNull UserVo userVo) {
        logger.debug("wxLogin userVo: {}", userVo);

        if (null != userVo.getWeChatOpenId() && !userVo.getWeChatOpenId().trim().isEmpty()) {
            User user = userRep.findByWeChatOpenId(userVo.getWeChatOpenId());
            if (null != user) {
                user.setLastLoginTime(new Date());
                user = userRep.save(user);
            }
            return Result.ok(UserVo.convertUser(user));
        } else if (null != userVo.getId() && !userVo.getId().trim().isEmpty()) {
            //如果有userId则直接返回对象
            Optional<User> userOptional = userRep.findById(userVo.getId());
            if (!userOptional.isPresent()) {
                return Result.badArgumentValue();
            }
            return Result.ok(UserVo.convertUser(userOptional.get()));
        } else {
            //空则返回错误
            return Result.badArgumentValue();
        }
    }

    @Override
    public Result wxRegister(@NotNull UserVo userVo) {
        logger.debug("wxRegister userVo: {}", userVo);

        if (null != userVo.getWeChatOpenId() && !userVo.getWeChatOpenId().trim().isEmpty() && null != userVo.getPhone() && !userVo.getPhone().trim().isEmpty()) {
            Object redisCode = redisService.get(projTag + userVo.getPhone());
            if (null == redisCode) {
                return Result.fail(Constant.REQUEST_FAIL_CODE, "验证码失效");
            }
            String redisCodeStr = String.valueOf(redisCode);
            if (null == userVo.getValidateCode() || !userVo.getValidateCode().equals(redisCodeStr)) {
                return Result.fail(Constant.REQUEST_FAIL_CODE, "验证码错误");
            }
            User user = userRep.findByPhone(userVo.getPhone());
            if (null != user) {
                user.setWeChatOpenId(userVo.getWeChatOpenId());
            } else {
                user = new User();
                AbstractMyBeanUtils.copyProperties(userVo, user);
            }
            user.setLastLoginTime(new Date());
            user.setRegisterTime(new Date());
            user = userRep.save(user);
            return Result.ok(UserVo.convertUser(user));
        } else {
            return Result.badArgumentValue();
        }
    }

    @Override
    public Result sendMsgValidateCode(@NotNull String phone) {
        logger.debug("sendMsgValidateCode phone: {}", phone);
        if (phone.isEmpty()) {
            return Result.badArgumentValue();
        }
        redisService.remove(projTag + phone);

        DefaultProfile profile = DefaultProfile.getProfile("default", shortMessageAccesskeyId, shortMessageSecret);
        IAcsClient client = new DefaultAcsClient(profile);


        CommonRequest request = new CommonRequest();

        request.setMethod(MethodType.POST);
        request.setDomain(shortMessageDomain);
        request.setVersion("2017-05-25");
        request.setAction(shortMessageAction);
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", shortMessageSignName);
        request.putQueryParameter("TemplateCode", shortMessageTemp);

        int random = (int) ((Math.random() * 9 + 1) * 100000);
        request.putQueryParameter("TemplateParam", "{ \"code\":\"" + random + "\"}");

        try {
            CommonResponse response = client.getCommonResponse(request);


            redisService.set(projTag + phone, random);

            final Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    redisService.remove(projTag + phone);
                    timer.cancel();
                }
            }, 5 * 60 * 1000);

        } catch (Exception e) {
            logger.error(e.getMessage());
            return Result.fail(Result.ERROR_CODE, "短信服务异常");
        }
        return Result.ok();
    }
}
